package net.roobook.cms.modules.admin.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.utils.CaptchaUtil;
import net.roobook.cms.common.constant.BaseConstant;
import net.roobook.cms.common.entity.ResResult;
import net.roobook.cms.common.entity.StateCodeEnum;
import net.roobook.cms.common.web.BaseController;
import net.roobook.cms.modules.admin.entity.Menu;
import net.roobook.cms.modules.admin.entity.User;
import net.roobook.cms.modules.admin.entity.req.LoginReq;
import net.roobook.cms.modules.admin.service.MenuService;
import net.roobook.cms.modules.admin.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.util.List;

/**
 * @author cos
 * @email 327878610@qq.com
 * @link https://roobook.net
 * @Description 用户登录相关，不需要做登录限制
 * @date 2023/9/22 14:18
 **/
@Controller
@RequestMapping("/admin/login")
public class LoginController extends BaseController {
    @Autowired
    private UserService userService;

    @Autowired
    private MenuService menuService;
    /**
     * 登录跳转
     *
     * @return
     */
    @RequestMapping("toLogin")
    public ModelAndView toLogin() {
        ModelAndView mv = new ModelAndView();
        RSA rsa = new RSA();

        session.setAttribute(BaseConstant.RSA_PRIVATE_KEY, rsa.getPrivateKeyBase64());

        mv.addObject("publicKey", rsa.getPublicKeyBase64());
        mv.setViewName("admin/login");
        return mv;
    }

    /**
     * 首页跳转
     *
     * @return
     */
    @RequestMapping("toIndex")
    public ModelAndView toIndex() {
        ModelAndView mv = new ModelAndView();
        String userId = (String) StpUtil.getLoginId();
        /**
         * 查询当前用户所拥有的菜单权限
         */
        List<Menu> menus = menuService.queryListByUserId(userId);
        mv.addObject("menus", menus);
        mv.setViewName("admin/index");
        return mv;
    }


    // 产生验证码
    @RequestMapping("/getVerifyCode")
    public void getKaptcha() throws IOException {
        ArithmeticCaptcha captcha = new ArithmeticCaptcha(130, 48);
        captcha.getArithmeticString();  // 获取运算的公式：3+2=?
        captcha.text();  // 获取运算的结果：5
        CaptchaUtil.out(captcha, request, response);
    }

    @RequestMapping(value = "login", method = RequestMethod.POST)
    @ResponseBody
    public ResResult login(@RequestBody LoginReq entity) {
        ResResult result = null;
        // 验证码校验
        if(!CaptchaUtil.ver(entity.getVcode(), request)) {
            result = ResResult.Factory.newInstance(Boolean.FALSE,
                    StateCodeEnum.USER_CODE_ERROR.getCode(), null,
                    StateCodeEnum.USER_CODE_ERROR.getDescription());
            return result;
        }

        // 清除验证码
        CaptchaUtil.clear(request);

        // 用户名和密码解密
        String privateKey = (String) session.getAttribute(BaseConstant.RSA_PRIVATE_KEY);
        RSA rsa = new RSA(privateKey, null);
        String username = new String(rsa.decrypt(entity.getUsername(), KeyType.PrivateKey));
        String password = new String(rsa.decrypt(entity.getPassword(), KeyType.PrivateKey));
        User user = userService.getByUserName(username);
        // 判断用户是否存在
        if(null == user){
            result = ResResult.Factory.newInstance(Boolean.FALSE,
                    StateCodeEnum.USER_PASSWORD_ERROR.getCode(),
                    null,
                    StateCodeEnum.USER_PASSWORD_ERROR.getDescription());
            return result;
        }
        // 判断用户状态是否被禁用
        if(user.getStatus() == 0){
            result = ResResult.Factory.newInstance(Boolean.FALSE,
                    StateCodeEnum.USER_MOBILE_EXCEPTION.getCode(),
                    null,
                    StateCodeEnum.USER_MOBILE_EXCEPTION.getDescription());
            return result;
        }

        String pwd = user.getPassword();
        String salt = user.getSalt();

        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String digestHex = md5.digestHex(salt+password);
        // 此处仅作模拟示例，真实项目需要从数据库中查询数据进行比对
        if(user.getUsername().equals(username) && user.getPassword().equals(digestHex)) {
            StpUtil.login(user.getId());
            result = ResResult.Factory.newInstance(Boolean.TRUE,
                    StateCodeEnum.USER_LOGIN_SUCCESS.getCode(), null,
                    StateCodeEnum.USER_LOGIN_SUCCESS.getDescription());
            return result;
        }else{
            result = ResResult.Factory.newInstance(Boolean.FALSE,
                    StateCodeEnum.USER_PASSWORD_ERROR.getCode(), null,
                    StateCodeEnum.USER_PASSWORD_ERROR.getDescription());
            return result;
        }
    }

    @RequestMapping("logout")
    public String logout() {
        StpUtil.logout();
        return "redirect:/admin/login/toLogin";
    }
}
